﻿using System;
using System.IO;
using System.Linq;

namespace DiskUsage.CoreLib
{
    public static class DirectorySizeTreeCreator
    {
        private static ISizeStore s_sizeStore = SizeStoreFactory.GetSizeStore();
        public static DirectoryEntry CreateTree(string path)
        {
            var root = new DirectoryEntry(path);
            CreateTree(root);
            return root;
        }

        private static long CreateTree(DirectoryEntry directoryEntry)
        {
            switch (directoryEntry.Type)
            {
                case PathType.Directory:
                    string[] dirs, files;
                    try
                    {
                        dirs = Directory.GetDirectories(directoryEntry.Path);
                    }
                    catch (Exception ex)
                    {
                        directoryEntry.Errors[ex] = "Error getting sub directories.";
                        dirs = new string[0];
                    }

                    try
                    {
                        files = Directory.GetFiles(directoryEntry.Path);
                    }
                    catch (Exception ex)
                    {
                        directoryEntry.Errors[ex] = "Error getting files";
                        files = new string[0];
                    }

                    foreach (var path in dirs.Union(files))
                    {
                        var child = new DirectoryEntry(path);
                        directoryEntry.Children.Add(child);
                        directoryEntry.Size += CreateTree(child);
                    }
                    s_sizeStore.SetSize(directoryEntry.Path, directoryEntry.Size);
                    break;

                case PathType.File:
                    try
                    {
                        directoryEntry.Size = new FileInfo(directoryEntry.Path).Length;
                        s_sizeStore.SetSize(directoryEntry.Path, directoryEntry.Size);
                    }
                    catch (Exception ex)
                    {
                        directoryEntry.Errors[ex] = "Error getting file size";
                        directoryEntry.Size = 0;
                    }
                    break;
            }
            return directoryEntry.Size;
        }
    }
}
